package com.example.qcweb;

import android.util.Log;
import android.util.Xml;

import com.example.modal.QcCard;

import org.xmlpull.v1.XmlPullParser;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 对pull解析xml进行了封装，不用给每个xml，再创建一个对应的解析类
 *
 * @author steven
 *         <p/>
 *         http://www.juziku.com/sunlightcs/
 */
public class XmlParse {

    /**
     * 解析XML
     *
     * @param is        xml字节流
     * @param clazz     字节码      如：Object.class
     * @param startName 开始位置
     * @return 返回List列表
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public List getXmlList(InputStream is, Class<?> clazz, String startName) {
        List list = null;
        XmlPullParser parser = Xml.newPullParser();
        Object object = null;
        try {
            parser.setInput(is, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        list = new ArrayList<Object>();
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        String name = parser.getName();
                        if (startName.equals(name)) {
                            object = clazz.newInstance();
                            //判断标签里是否有属性，如果有，则全部解析出来
                            int count = parser.getAttributeCount();
                            for (int i = 0; i < count; i++)
                                setXmlValue(object, parser.getAttributeName(i), parser.getAttributeValue(i));
                        } else if (object != null) {
                            setXmlValue(object, name, parser.nextText());
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if (startName.equals(parser.getName())) {
                            list.add(object);
                            object = null;
                        }
                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            Log.e("xml pull error", e.toString());
        }
        return list;
    }


    /**
     * 解析XML
     *
     * @param is    xml字节流
     * @param clazz 字节码      如：Object.class
     * @return 返回Object
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public Object getXmlObject1(InputStream is, Class<?> clazz, String startname) {
        XmlPullParser parser = Xml.newPullParser();
        Object object = null;
//		List list = null;
        Object subObject = null;
        //	String subName = null;
        try {
            parser.setInput(is, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        //	object = clazz.newInstance();
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        String name = parser.getName();
                        if (startname.equals(name)) {
                            object = clazz.newInstance();
                            //判断标签里是否有属性，如果有，则全部解析出来
                            int count = parser.getAttributeCount();
                            for (int i = 0; i < count; i++)
                                setXmlValue(object, parser.getAttributeName(i), parser.getAttributeValue(i));
                        } else if (object != null) {
                            String nextString = parser.nextText();
                            setXmlValue(object, name, nextString);
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if (startname.equals(parser.getName())) {
                            subObject = object;
                            object = null;
                        }
                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            Log.e("xml pull error", e.getMessage());
        }
        return subObject;
    }


    @SuppressWarnings({"unchecked", "rawtypes"})
    public Object getXmlObject(InputStream is, Class<?> clazz) {
        XmlPullParser parser = Xml.newPullParser();
        Object object = null;
        List list = null;
        Object subObject = null;
        Object subObject2 = null;
        String subName = null;
        try {
            parser.setInput(is, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        object = clazz.newInstance();
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        String name = parser.getName();

                        Field[] f = null;
                        if (subObject == null) {
                            f = object.getClass().getDeclaredFields();

                            //判断标签里是否有属性，如果有，则全部解析出来
                            int count = parser.getAttributeCount();
                            for (int j = 0; j < count; j++)
                                setXmlValue(object, parser.getAttributeName(j), parser.getAttributeValue(j));
                        } else {
                            f = subObject.getClass().getDeclaredFields();
                        }

                        for (int i = 0; i < f.length; i++) {

                            if (f[i].getName().equalsIgnoreCase(name)) {
                                //	String typeString=f[i].getType().getName();
                                //	String typeString2=f[i].getGenericType().toString();
                                //	String nameString=f[i].getName();
                                //	String superString=f[i].getClass().getGenericSuperclass().toString();
                                //	subObject2=f[i].getClass().newInstance();
                                //	String 	f[i].getClass().getSimpleName();
                                //判断是不是List类型
                                if (f[i].getType().getName().equals("java.util.List")) {
                                    Type type = f[i].getGenericType();
                                    if (type instanceof ParameterizedType) {
                                        //获得泛型参数的实际类型
                                        Class<?> subClazz = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
                                        subObject = subClazz.newInstance();
                                        subName = f[i].getName();

                                        //判断标签里是否有属性，如果有，则全部解析出来
                                        int count = parser.getAttributeCount();
                                        for (int j = 0; j < count; j++)
                                            setXmlValue(subObject, parser.getAttributeName(j), parser.getAttributeValue(j));

                                        if (list == null) {
                                            list = new ArrayList<Object>();
                                            f[i].setAccessible(true);
                                            f[i].set(object, list);
                                        }
                                    }
                                } else {   //普通属性
                                    if (subObject != null) {
                                        setXmlValue(subObject, name, parser.nextText());
                                    } else {
                                        Type type2 = f[i].getGenericType();
                                        if (type2 instanceof ParameterizedType) {
                                            Class<?> subClazz2 = (Class<?>) ((ParameterizedType) type2).getActualTypeArguments()[0];
                                            subObject2 = subClazz2.newInstance();
                                        }
                                        setXmlValue(subObject2, name, parser.nextText());
                                    }
                                }
                                break;
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if (subObject != null && subName.equalsIgnoreCase(parser.getName())) {
                            list.add(subObject);
                            subObject = null;
                            subName = null;
                        }
                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            Log.e("xml pull error", e.getMessage());
        }
        return object;
    }

    /**
     * 把xml标签的值，转换成对象里属性的值
     *
     * @param t     对象
     * @param name  xml标签名
     * @param value xml标签名对应的值
     */

    @SuppressWarnings({"unchecked", "rawtypes"})
    public Object getXmlObject2(InputStream is, Class<?> clazz) {
        XmlPullParser parser = Xml.newPullParser();
        Object object = null;
        List<Object> list = null;
        Object subObject = null;
        Object subObject2 = null;
        String subName = null;
        String subName1 = null;
        boolean islistobj = false;
        String objname = null;
        Class<?> subClazz = null;
        try {
            parser.setInput(is, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        object = clazz.newInstance();
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        String name = parser.getName();

                        Field[] f = null;
                        if (islistobj == true) {


                            if (objname.equals(name)) {
                                //创建新对象
                                //	subObject3=subObject2;
                                subObject2 = subClazz.newInstance();
                                subName1 = name;
                            } else {
                                //普通属性
                                setXmlValue(subObject2, name, parser.nextText());
                            }
                        } else {
                            if (subObject == null) {
                                f = object.getClass().getDeclaredFields();

                                //判断标签里是否有属性，如果有，则全部解析出来
                                int count = parser.getAttributeCount();
                                for (int j = 0; j < count; j++)
                                    setXmlValue(object, parser.getAttributeName(j), parser.getAttributeValue(j));
                            } else {
                                f = subObject.getClass().getDeclaredFields();
                            }
                            for (int i = 0; i < f.length; i++) {
                                if (f[i].getName().equalsIgnoreCase(name)) {
                                    String typeString = f[i].getType().getName();
                                    //判断是不是List类型
                                    if (f[i].getType().getName().equals("java.util.List")) {
                                        Type type = f[i].getGenericType();
                                        if (type instanceof ParameterizedType) {
                                            //获得泛型参数的实际类型
                                            subClazz = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
                                            subObject = subClazz.newInstance();
                                            //			subObject=subObject2;
                                            objname = subObject.getClass().getSimpleName();
                                            islistobj = true;
                                            subName = f[i].getName();

                                            //判断标签里是否有属性，如果有，则全部解析出来
                                            int count = parser.getAttributeCount();
                                            for (int j = 0; j < count; j++)
                                                setXmlValue(subObject, parser.getAttributeName(j), parser.getAttributeValue(j));

                                            if (list == null) {
                                                list = new ArrayList<Object>();
                                                f[i].setAccessible(true);
                                                f[i].set(object, list);
                                            }
                                        }
                                    } else if (f[i].getType().getName().equals("com.example.modal.QcCard")) {
                                        subName = f[i].getName();
                                        QcCard qcCard = new QcCard();
                                        subObject = qcCard;
                                        f[i].setAccessible(true);
                                        f[i].set(object, subObject);

                                    } else {
                                        //普通属性
                                        if (subObject != null) {
                                            setXmlValue(subObject, name, parser.nextText());

                                        } else {

                                        }

                                    }
                                    break;
                                }
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if (subObject != null && subName.equalsIgnoreCase(parser.getName())) {//若为qccard或者list结尾的时候
                            list = null;
                            subObject2 = null;
                            islistobj = false;
                            subObject = null;
                            subName = null;

                        } else if (islistobj == true && subName1.equalsIgnoreCase(parser.getName())) {//若为对象
                            list.add(subObject2);

                        }

                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            Log.e("xml pull error", e.getMessage());
        }
        return object;
    }

    private void setXmlValue(Object t, String name, String value) {
        try {
            Field[] f = t.getClass().getDeclaredFields();
            for (int i = 0; i < f.length; i++) {
                if (f[i].getName().equalsIgnoreCase(name)) {
                    f[i].setAccessible(true);
                    //获得属性类型
                    Class<?> fieldType = f[i].getType();

                    if (fieldType == String.class) {
                        f[i].set(t, value);
                    } else if (fieldType == Integer.TYPE) {
                        f[i].set(t, Integer.parseInt(value));
                    } else if (fieldType == Float.TYPE) {
                        f[i].set(t, Float.parseFloat(value));
                    } else if (fieldType == Double.TYPE) {
                        f[i].set(t, Double.parseDouble(value));
                    } else if (fieldType == Long.TYPE) {
                        f[i].set(t, Long.parseLong(value));
                    } else if (fieldType == Short.TYPE) {
                        f[i].set(t, Short.parseShort(value));
                    } else if (fieldType == Boolean.TYPE) {
                        f[i].set(t, Boolean.parseBoolean(value));
                    } else {
                        f[i].set(t, value);
                    }
                }
            }
        } catch (Exception e) {
            Log.e("xml error", e.toString());
        }
    }

}
